<?php
namespace soa\partner\zt;

use artisan\http;
use soa\check\EnvCheck;

/**
 * 中通订单服务API
 *
 * 文档：
 *
 *
 * @package soa\partner\zt
 */
class ZtOrder
{
    // 快宝合作商编号
    private $companyId = 'Kuaibao';

    // 快宝合作商签名
    private $partnerId = 'fde099cd2cf60738d765c48afb252a58';

    /**
     * 获取中通接口地址
     *
     * @param string $route
     * @return string
     */
    private function getApi($route = '')
    {
        $url = 'http://japi.zto.cn/zto/api_utf8/commonOrder';

        $isOnlineEnv = (new EnvCheck())->isEnvOnline();

        $testIpArr = ['127.0.0.1', '192.168.1.81', '121.41.38.122'];
        if (in_array($_SERVER['SERVER_ADDR'], $testIpArr) || !$isOnlineEnv) {
            $url = 'http://58.40.16.125:9001/zto/api_utf8/commonOrder';
        }

        return $url;
    }

    /**
     * 提交订单到中通
     *
     * @param array $orderParams
     *  $orderParams = [
     *      'partnerCode' => $order['id'], // 合作商订单号(本地订单号)
     *      'sender' => [
     *          'id' => $order['shipper_uid'],
     *          'name' => $order['shipper_name'],
     *          'mobile' => $order['shipper_mobile'],
     *          'prov' => $order['shipper_province'],
     *          'city' => $order['shipper_city'],
     *          'county' => $order['shipper_district'],
     *          'address' => $order['shipper_address']
     *      ],
     *      'receiver' => [
     *          'name' => $order['shipping_name'],
     *          'mobile' => $order['shipping_mobile'],
     *          'prov' => $order['shipping_province'],
     *          'city' => $order['shipping_city'],
     *          'county' => $order['shipping_district'],
     *          'address' => $order['shipping_address']
     *      ],
     *      'items' => [
     *          [
     *              'name' => $order['package_note'],
     *              'weight' => 0
     *          ]
     *      ]
     *  ];
     * @return array
     */
    public function add(array $orderParams)
    {
        // 数据验证
        if (!$orderParams['sender']['mobile']) {
            return [
                'status' => false,
                'msg' => '发件人手机必填',
                'data' => ''
            ];
        }
        // 收发件人姓名不能超过24个长度
        if (strlen($orderParams['sender']['name']) > 24) {
            $orderParams['sender']['name'] = mb_substr($orderParams['sender']['name'], 0, 12);
        }
        if (strlen($orderParams['receiver']['name']) > 24) {
            $orderParams['receiver']['name'] = mb_substr($orderParams['receiver']['name'], 0, 12);
        }

        $reqParams = $this->getReqParams('CREATE', $orderParams);

        // 成功 {"orderCode":"ZT1704050000625780","reason":"","result":true}
        // 失败 {"orderCode":null,"reason":"json格式转换错误","result":false}
        // 失败 {"data":null,"msg":"非法的msgType","status":false}
        $response = json_decode($this->request($this->getApi(), $reqParams), true);
        if (!is_array($response) || !isset($response['result']) || $response['result'] == false) {
            logError($response, 'zt-api-add', '中通接口下单失败');
            return [
                'status' => false,
                'msg' => $response['reason'] ?: $response['msg'],
                'data' => $response['orderCode'] ?: $response['data']
            ];
        }

        return [
            'status' => true,
            'msg' => $response['reason'] ?: $response['msg'],
            'data' => $response['orderCode'] ?: $response['data']
        ];
    }

    /**
     * 提交订单到中通（可以指定快递员）
     *
     * @param array $orderParams
     *  $orderParams = [
     *      'partnerCode' => $order['id'], // 合作商订单号(本地订单号)
     *      'sender' => [
     *          'id' => $order['shipper_uid'],
     *          'name' => $order['shipper_name'],
     *          'mobile' => $order['shipper_mobile'],
     *          'prov' => $order['shipper_province'],
     *          'city' => $order['shipper_city'],
     *          'county' => $order['shipper_district'],
     *          'address' => $order['shipper_address']
     *      ],
     *      'receiver' => [
     *          'name' => $order['shipping_name'],
     *          'mobile' => $order['shipping_mobile'],
     *          'prov' => $order['shipping_province'],
     *          'city' => $order['shipping_city'],
     *          'county' => $order['shipping_district'],
     *          'address' => $order['shipping_address']
     *      ],
     *      'items' => [
     *          [
     *              'name' => $order['package_note'],
     *              'weight' => 0
     *          ]
     *      ],
     *      'siteCode' => $siteCode,   // 网点编号
     *      'empCode' => $empCode,    // 员工编号
     *  ];
     * @return array
     */
    public function addByEmp(array $orderParams)
    {
        $reqParams = $this->getReqParams('CREATE_EMP', $orderParams);

        // 成功 {"orderCode":"ZT1704050000625780","reason":"","result":true}
        // 失败 {"orderCode":null,"reason":"json格式转换错误","result":false}
        // 失败 {"data":null,"msg":"非法的msgType","status":false}
        $response = json_decode($this->request($this->getApi(), $reqParams), true);
        if (!is_array($response) || !isset($response['result']) || $response['result'] == false) {
            logError($response, 'zt-api-add-emp', '快递员通过中通接口下单失败');
            return [
                'status' => false,
                'msg' => $response['reason'] ?: $response['msg'],
                'data' => $response['orderCode'] ?: $response['data']
            ];
        }

        return [
            'status' => true,
            'msg' => $response['reason'] ?: $response['msg'],
            'data' => $response['orderCode'] ?: $response['data']
        ];
    }

    /**
     * @param array $orderParams
     *   $orderParams = [
     *      [
     *          'orderCode' => $order['third_party_orderid'], // 第三方订单号
     *          'fieldName' => 'status',
     *          'fieldValue' => 'cancel',
     *          'reason' => '客户取消订单'
     *      ]
     *  ];
     *
     * @return array
     */
    public function cancel(array $orderParams)
    {
        $reqParams = $this->getReqParams('UPDATE', $orderParams);

        // 成功 {"data":[{"fieldName":"status","orderCode":"ZT1704050000625788","partnerCode":"","partnerId":"","reason":"客户取消订单","result":true}],"msg":"","status":true}
        // 失败 {"data":[{"fieldName":"status","orderCode":"ZT170405000062578859","partnerCode":"","partnerId":"","reason":"该orderCode不存在","result":false}],"msg":"","status":true}
        $response = json_decode($this->request($this->getApi(), $reqParams), true);
        logError($response, 'zt-cancel-order', '通过中通接口取消订单失败');
        if (!is_array($response) || !isset($response['data'][0]['result']) || $response['data'][0]['result'] == false) {
            return [
                'status' => false,
                'msg' => $response['data'][0]['reason'],
                'data' => ''
            ];
        }

        return [
            'status' => true,
            'msg' => $response['data'][0]['reason'],
            'data' => ''
        ];
    }


    /**
     * 获取请求包体
     *
     * @param $msgType 请求类型 如：CREATE、UPDATE
     * @param array $msgParams 请求参数
     * @return array
     */
    private function getReqParams($msgType, array $msgParams)
    {
        //将data转换为json
        $data = json_encode($msgParams);

        $reqParams = [
            'data_digest' => (base64_encode(md5($data . $this->partnerId, true))),
            'msg_type' => $msgType,
            'company_id' => $this->companyId,
            'data' => $data
        ];

        return $reqParams;
    }

    protected function request($url, array $params)
    {
        return http::post($url, $params, [
            'TIMEOUT' => 100,
            'HTTPHEADER' => ['Content-type:application/x-www-form-urlencoded; charset=GBK']
        ]);
    }

}